home *** CD-ROM | disk | FTP | other *** search
- #!/usr/app/bin/perl
-
- eval 'exec /usr/app/bin/perl -S $0 ${1+"$@"}'
- if 0; # not running under some shell
- # pcg@goof.com
- # a fairly complete miff save filter
-
- use Gimp;
- use Gimp::Fu;
- use Gimp::UI;
- use Fcntl;
-
- # Gimp::set_trace(TRACE_ALL);
-
- sub write_layer {
- my($fh,$l)=@_;
- my($w,$h)=($l->width,$l->height);
- my $r = new PixelRgn $l,0,0,$w,$h,0,0;
- print $fh "rows=$h columns=$w\n",
- "matte=", $r->bpp&1 ? "False" : "True", "\n",
- ":\012";
- # inefficient as hell, but "what shells?" ;*>
- for my $y (0..$h-1) {
- print $fh $r->get_rect2(0,$y,$w,1);
- }
- }
-
- register "file_miff_save",
- "save images as miff (Magick Interchange File Format)",
- "Saves images in the miff (Magick Interchange File Format) format used by the ImageMagick package",
- "Marc Lehmann",
- "Marc Lehmann <pcg\@goof.com>",
- "1999-10-26",
- "<Save>/MIFF",
- "RGB, RGBA, GRAY", # weird, but no matte for !DirectColour
- [],
- sub {
- my($img,$drawable,$filename) = @_;
- my($new_img,$new_drawable);
- my $export = Gimp::UI::export_image ($new_img=$img, $new_drawable=$drawable, "MIFF",
- EXPORT_CAN_HANDLE_GRAY|EXPORT_CAN_HANDLE_RGB|EXPORT_CAN_HANDLE_ALPHA |EXPORT_CAN_HANDLE_LAYERS|EXPORT_CAN_HANDLE_LAYERS_AS_ANIMATION);
- die "export failed" if $export == EXPORT_CANCEL;
- my @layers = $new_img->get_layers;
-
- sysopen FILE,$filename,O_CREAT|O_TRUNC|O_WRONLY or die "Unable to open '$filename' for writing: $!\n";
- my $hdr = eval { $img->parasite_find("gimp-comment")->data };
- $hdr = " COMMENT: $hdr\n" if $hdr;
- $hdr = <<EOF;
- id=ImageMagick
- {
- CREATOR: file_miff_save gimp plug-in, see http://www.gimp.org/
- $hdr}
- EOF
-
- Gimp->tile_cache_ntiles($img->width / Gimp->tile_width + 1);
-
- init Progress "Saving '$filename' as MIFF...";
- my $scene = 0;
- for (@layers) {
- print FILE $hdr,
- "scene=$scene\n",
- "class=", $_->is_rgb ? "DirectClass" : "PseudoClass", "\n";
- #"gamma=", Gimp->gamma, "\n";
- # resolution etc..
- write_layer(*FILE,$_);
- $scene++;
- update Progress $scene/@layers;
- }
- close FILE;
- $new_img->delete if $export == EXPORT_EXPORT;
- ();
- };
-
- sub read_layer {
- my($img)=shift;
- local $_=shift;
- my($w,$h,$d)=($_->{columns},$_->{rows},$_->{_bpp});
-
- my $l = new Layer $img, $w, $h,
- (
- $d == 1 ? GRAY_IMAGE
- : $d == 2 ? GRAYA_IMAGE
- : $d == 3 ? RGB_IMAGE
- : $d == 4 ? RGBA_IMAGE
- : die "Unsupported image depth ($d channels)\n"
- ),
- $_->{scene}, 100, NORMAL_MODE;
-
- $l->add_layer($_->{scene});
-
- my $r = new PixelRgn $l,0,0,$w,$h,1,0;
- seek FILE, $_->{_offset}, 0;
-
- for my $y (0..$h-1) {
- read FILE, $_, $w * $d;
- $r->set_rect2($_,0,$y);
- }
- undef $r;
- $l;
- }
-
- register "file_miff_load",
- "load miff images (Magick Interchange File Format)",
- "Loads images that were saved in the miff (Magick Interchange File Format) format used by the ImageMagick package",
- "Marc Lehmann",
- "Marc Lehmann <pcg\@goof.com>",
- "1999-09-14",
- "<Load>/MIFF",
- undef,
- [],
- sub {
- my($filename) = @_;
- sysopen FILE,$filename,O_RDONLY or die "Unable to open '$filename' for reading: $!\n";
- my(@scenes);
- my $comment;
- seek FILE, 0, 2; my $filesize = tell FILE; seek FILE, 0, 0;
- local $/ = "\012";
- init Progress "Loading MIFF image from '$filename'...";
- do {
- my %h;
- header:
- while (<FILE>) {
- die "Unexpected end of file while reading from '$filename'\n" if eof;
- while($_ =~ /\S/) {
- if (/:\012$/) {
- last header;
- } elsif (s/^\s*(\w+)=(\S+|"(?:[^\\"]+|\\"|\\)*")//) {
- $h{$1}=$2;
- } elsif (s/\s*\{//) {
- while(!s/([^}]*)}//) {
- $comment .= $_;
- $_ = <FILE>;
- die "Unexpected end of file while reading comment block from '$filename'\n" if eof;
- }
- $comment .= $1;
- } else {
- die "Unparseable header line ($_) while reading '$filename'\n";
- }
- }
- }
-
- die "No ImageMagick header found in '$filename'\n" unless $h{id} eq "ImageMagick";
-
- $h{_bpp} = ($h{class} =~ /PseudoClass/ ? 1 : 3)
- + ($h{matte} =~ /True/i ? 1 : 0);
- $h{_size} = $h{rows} * $h{columns} * $h{_bpp};
- $h{_offset} = tell;
- push @scenes, \%h;
-
- seek FILE, $h{_size}, 1;
- update Progress tell()/$filesize*0.2;
- } while !eof;
-
- my ($w,$h,$d);
- for (@scenes) {
- $w = $_->{columns} if $_->{columns} > $w;
- $h = $_->{rows} if $_->{rows} > $h;
- $d = $_->{_bpp} if $_->{_bpp} > $d;
- }
-
- my $img = new Image $w, $h, $d >= 3 ? RGB : GRAY;
- $img->set_filename($filename);
- $img->undo_disable;
-
- if ($comment) {
- $comment =~ s/^\s+//s;
- $comment =~ s/\s+$//s;
- $img->parasite_attach (new GimpParasite "gimp-comment", PARASITE_PERSISTENT, $comment);
- }
- # resolution etc..
-
- Gimp->tile_cache_ntiles($w / Gimp->tile_width + 1);
-
- # horrors, reverse, and line-by-line (!!)
- for (@scenes) {
- my $layer = read_layer $img,$_;
- update Progress tell()/$filesize*0.8 + 0.2;
- }
-
- $img->undo_enable;
- $img;
- };
-
- Gimp::on_query {
- Gimp->register_magic_load_handler("file_miff_load", "miff", "", "0,string,id=ImageMagick");
- Gimp->register_save_handler("file_miff_save", "miff", "");
- };
-
- exit main;
-
-